package com.huayi.datagovernance.utils;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.sql.Blob;


//@Data
@Slf4j
public class TopoUtil {

    public static String saxBlob(Object object){
        Blob blob = (Blob)object;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int len;
        String result = "";

        try {
            InputStream is = blob.getBinaryStream();
            while ((len = is.read()) != -1) {
                out.write(len);
            }
            String hex = byteArrayToHex(out.toByteArray());
            if(!hex.equals("")){
                result = splitTopRecord(hex);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String byteArrayToHex(byte[] bytes){
        StringBuilder sb = new StringBuilder();
        for (int i=0;i<bytes.length;i++){
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if(hex.length() == 1){
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public static String splitTopRecord(String hex) {
        //todo 需要考虑超过2的端子的时候
//        0203f059010000000024f0590100000000
        String record = "";
        int num = Integer.parseInt(hex.substring(0, 2));
        if (num == 1) {
            record = hexToNumber(hex.substring(2, 18));
        } else if (num == 2) {
            record = hexToNumber(hex.substring(2, 18));
            record += "|";
            record += hexToNumber(hex.substring(18));
        }
        return record;
    }

    private static String hexToNumber(String hex) {
        long n = 0;

        BigInteger bi;
        for (int i = 1; i <= 8; i++) {
            if (i == 8) {
                bi = new BigInteger(hex.substring(i * 2 - 2), 16);
            } else {
                bi = new BigInteger(hex.substring(i * 2 - 2, i * 2), 16);
            }
            long i0 = bi.longValue();

            long i1 = (long) (i0 * Math.pow(256, i - 1));
            n += i1;
        }
        return String.valueOf(n);
    }
    public static OMElement findAPathByDocument(String topoService, String mapId, String objectId1,  String objectId2,
                                         String isDevStatus, String versionNo){
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");

        OMElement method = fac.createOMElement("FindAPathReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("ObjectId1", omNs);
        symbol2.setText(objectId1);
        OMElement symbol3 = fac.createOMElement("ObjectId2", omNs);
        symbol3.setText(objectId2);
        OMElement symbol4 = fac.createOMElement("IsDevStatus", omNs);
        symbol4.setText(isDevStatus);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            f.printStackTrace();
            return null;
        }
    }

    /**
     * 拓扑检测
     * @param topoService
     * @param mapId
     * @param classid
     * @param oid
     * @param layer
     * @param versionNo
     * @return
     */
    public static OMElement topoCheckByDocument(String topoService, String mapId, String classid, String oid,
                                                 String layer, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("TopoCheckReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("classid", omNs);
        symbol2.setText(classid);
        OMElement symbol3 = fac.createOMElement("oid", omNs);
        symbol3.setText(oid);
        OMElement symbol4 = fac.createOMElement("Layer", omNs);
        symbol4.setText(layer);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }

    public static OMElement topoSearchByDocument(String topoService, String mapId, String objectId, String isDevStatus,
                                                 String searchConditions, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("TopoSearchReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("ObjectId", omNs);
        symbol2.setText(objectId);
        OMElement symbol3 = fac.createOMElement("IsDevStatus", omNs);
        symbol3.setText(isDevStatus);
        OMElement symbol4 = fac.createOMElement("SearchConditions", omNs);
        symbol4.setText(searchConditions);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }

    public static OMElement TopoCheckRespByDocument(String topoService, String mapId, String classid, String oid,
                                                 String layer, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("TopoCheckReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("classid", omNs);
        symbol2.setText(classid);
        OMElement symbol3 = fac.createOMElement("oid", omNs);
        symbol3.setText(oid);
        OMElement symbol4 = fac.createOMElement("Layer", omNs);
        symbol4.setText(layer);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }

    /**
     * axis2通过document方式调用拓扑服务
     * @param topoService 拓扑地址
     * @param mapId 图实例
     * @param objectId
     * @param termIds
     * @param Typein
     * @param versionNo
     * @return
     */
    public static OMElement queryByObjectByDocument(String topoService, String mapId, String objectId, String termIds, String Typein, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("QueryByObjectReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("ObjectId", omNs);
        symbol2.setText(objectId);
        OMElement symbol3 = fac.createOMElement("TermIds", omNs);
        symbol3.setText(termIds);
        OMElement symbol4 = fac.createOMElement("Typein", omNs);
        symbol4.setText(Typein);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }

    /**
     * axis2通过document方式调用拓扑服务
     * @param topoService 拓扑地址
     * @param mapId 图实例
     * @param objectId
     * @param termIds
     * @param Typein
     * @param versionNo
     * @return
     */
    public static OMElement queryByObjectExtByDocument(String topoService, String mapId, String objectId, String termIds, String Typein, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("QueryByObjectExtReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapId);
        OMElement symbol2 = fac.createOMElement("ObjectId", omNs);
        symbol2.setText(objectId);
        OMElement symbol3 = fac.createOMElement("TermIds", omNs);
        symbol3.setText(termIds);
        OMElement symbol4 = fac.createOMElement("Typein", omNs);
        symbol4.setText(Typein);
        OMElement symbol5 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol6 = fac.createOMElement("OutType", omNs);
        symbol6.setText("1");

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            log.info("topo服务报文：{}" , method.getText());
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            f.printStackTrace();
            return null;
        }
    }

    public static OMElement downStreamByDocument(String topoService, String mapid, String objectId, String voltageLevel, String switchConditions,
                                                 String sourceConditons, String filterSubtypes, String outType, String versionNo) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("DownStreamReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapid);
        OMElement symbol2 = fac.createOMElement("ObjectId", omNs);
        symbol2.setText(objectId);
        OMElement symbol3 = fac.createOMElement("VoltageLevel", omNs);
        symbol3.setText(voltageLevel);
        OMElement symbol4 = fac.createOMElement("SwitchConditions", omNs);
        symbol4.setText(switchConditions);
        OMElement symbol5 = fac.createOMElement("SourceConditions", omNs);
        symbol4.setText(sourceConditons);
        OMElement symbol6 = fac.createOMElement("FilterSubtypes", omNs);
        symbol4.setText(filterSubtypes);
        OMElement symbol7 = fac.createOMElement("VersionNo", omNs);
        symbol5.setText(versionNo);
        OMElement symbol8 = fac.createOMElement("OutType", omNs);
        symbol6.setText(outType);

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.addChild(symbol7);
        method.addChild(symbol8);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }

    public static OMElement upStreamReqByDocument(String topoService, String mapid, String objectId, String voltageLevel, String switchConditions,String sourceConditons, String versionNo, String outType) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        String tns = "http://www.sgcc.com.cn/sggis/service/gisservice";
        OMNamespace omNs = fac.createOMNamespace(tns, "");
        OMElement method = fac.createOMElement("DownStreamReq", omNs);
        OMElement symbol1 = fac.createOMElement("MapID", omNs);
        symbol1.setText(mapid);
        OMElement symbol2 = fac.createOMElement("ObjectId", omNs);
        symbol2.setText(objectId);
        OMElement symbol3 = fac.createOMElement("VoltageLevel", omNs);
        symbol3.setText(voltageLevel);
        OMElement symbol4 = fac.createOMElement("SwitchConditions", omNs);
        symbol4.setText(switchConditions);
        OMElement symbol5 = fac.createOMElement("SourceConditions", omNs);
        symbol5.setText(sourceConditons);
        OMElement symbol6 = fac.createOMElement("VersionNo", omNs);
        symbol6.setText(versionNo);
        OMElement symbol7 = fac.createOMElement("OutType", omNs);
        symbol7.setText(outType);

        method.addChild(symbol1);
        method.addChild(symbol2);
        method.addChild(symbol3);
        method.addChild(symbol4);
        method.addChild(symbol5);
        method.addChild(symbol6);
        method.addChild(symbol7);
        method.build();

        try {
            Options options = new Options();
            EndpointReference targetEPR = new EndpointReference(topoService);
            options.setTo(targetEPR);
            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(method);
            return result;
        } catch (AxisFault f) {
            return null;
        }
    }
}